package org.qloudgen.txn.dilithium.cluster.database;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.qloudgen.txn.dilithium.cluster.beans.Cluster;
import org.qloudgen.txn.dilithium.cluster.beans.ParameterBean;
import org.qloudgen.txn.dilithium.cluster.beans.RecordEntry;
import org.qloudgen.txn.dilithium.cluster.sqlmap.ConfigNames;

import org.qloudgen.txn.dilithium.cluster.common.CommonValues;

import com.google.common.collect.Lists;

public class ClusterImpl {
	
	static Log log = LogFactory.getLog(ClusterImpl.class);
	
	public final static List<Cluster> getClusterList(String userNo,List<Cluster> clusters){
		
		SqlSession sess = CommonValues.factory.openSession();
		if (clusters != null)
			clusters.clear();
		else
			clusters = Lists.newArrayList();
		
		List<Cluster> result = sess.selectList(ConfigNames.SELECT_CLUSTER_LIST,userNo);
		sess.close();
		clusters.addAll(result);
		return result;
				
	}
	
	public final static String getIpList(int clusterID){
		
		SqlSession sess = CommonValues.factory.openSession();
		Cluster cluster = sess.selectOne(ConfigNames.SELECT_CLUSTER,clusterID);
		List<String> result = sess.selectList(ConfigNames.SELECT_CLUSTER_NODE_IP,clusterID);
		sess.close();
		
		String ipList = cluster.getGtmMasterIp();
		
		if (cluster.getGtmSlaveIp() != null) ipList += " "  + cluster.getGtmSlaveIp();
		
		for (String ip : result){
			
			ipList += " "  + ip;
			
		}
		
		return ipList;
				
	}
	
	public final static void createCluster(Cluster cluster,List<ParameterBean> parameterList){
		
		if (cluster == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
			
			// insert cluster info 
			sess.insert(ConfigNames.INSERT_CLUSTER,cluster);
			
			// insert cluster conf
			if (cluster.getRadioChoice().equals("default") )
				sess.insert(ConfigNames.INSERT_DEFAULT_CONF, cluster.getClusterID());
			else {
				for (int i = 0; i < parameterList.size(); i++){
					sess.insert(ConfigNames.INSERT_UDF_CONF, parameterList.get(i).setClusterID(cluster.getClusterID()));
				}
			}
		sess.commit();
		sess.close();
	}
	
	public final static void initCluster(Cluster cluster){
		
		if (cluster == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		RecordEntry re = new RecordEntry();
		re.setClusterID(cluster.getClusterID());
		
		// insert cluster node
		for (int i = 0; i < cluster.getNodeIpsList().size(); i++){
			re.setEntryValue(cluster.getNodeIpsList().get(i));
			sess.insert(ConfigNames.INSERT_CLUSTER_NODE,re );
		}
		sess.commit();
		sess.close();
	}
	public final static int getClusterID() {

		SqlSession session = CommonValues.factory.openSession();
		int clusterID = session.selectOne(ConfigNames.SELECT_CLUSTERID);
		session.close();
		return clusterID;
	}

	public static void deleteClusterID(int clusterID) {
		
		SqlSession sess = CommonValues.factory.openSession(false);
		sess.delete(ConfigNames.DELETE_CLUSTER, clusterID);
		sess.delete(ConfigNames.DELETE_CLUSTER_NODE, clusterID);
		sess.delete(ConfigNames.DELETE_CLUSTER_CONF, clusterID);
		sess.delete(ConfigNames.DELETE_CLUSTER_CLIENT, clusterID);
		sess.commit();
		sess.close();
		
	}

	public static void updateClusterStatus(Cluster cluster) {
		
		SqlSession sess = CommonValues.factory.openSession(false);
		sess.update(ConfigNames.UPDATE_CLUSTER_STATUS, cluster);
		sess.commit();
		sess.close();
		
	}

	public static List<ParameterBean> getClusterConf(int clusterID) {
		
		SqlSession sess = CommonValues.factory.openSession();
		List<ParameterBean> result = sess.selectList(ConfigNames.SELECT_CONF,clusterID);
		sess.close();
		return result;
	}

	public static void updateClusterConf(ParameterBean param) {
		
		if (param == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		sess.update(ConfigNames.UPDATE_CLUSTER_CONF,param);
		sess.commit();
		sess.close();
		
	}

	public static void addNode(Cluster cluster) {
		
		if (cluster.getNewNodeIp() == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		// add new node
		sess.insert(ConfigNames.INSERT_CLUSTER_NODE,cluster);
		
		sess.commit();
		sess.close();
		
	}

	public static void getClusterNodeList(int clusterID, List<RecordEntry> nodes) {
		
		SqlSession sess = CommonValues.factory.openSession();
		
		nodes.clear();
		List<RecordEntry> nodeList = sess.selectList(ConfigNames.SELECT_CLUSTER_NODE,clusterID);
		nodes.addAll(nodeList);
		sess.close();
		
	}

	public static void getClusterClientList(int clusterID, List<RecordEntry> nodes) {
		
		SqlSession sess = CommonValues.factory.openSession();
		
		nodes.clear();
		List<RecordEntry> nodeList = sess.selectList(ConfigNames.SELECT_CLUSTER_CLIENT,clusterID);
		nodes.addAll(nodeList);
		sess.close();
		
	}

	public static void removeNode(Cluster cluster) {
		
		if (cluster.getNewNodeIp() == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		sess.delete(ConfigNames.REMOVE_CLUSTER_NODE,cluster);

		sess.commit();
		sess.close();
		
	}
	
	public static void addClient(Cluster cluster) {
		
		if (cluster.getNewNodeIp() == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		// add new node
		sess.insert(ConfigNames.INSERT_CLUSTER_CLIENT,cluster);
		
		sess.commit();
		sess.close();
		
	}

	public static void removeClient(Cluster cluster) {
		
		if (cluster.getNewNodeIp() == null) return;
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		sess.delete(ConfigNames.REMOVE_CLUSTER_CLIENT,cluster);

		sess.commit();
		sess.close();
		
	}

	public static List<ParameterBean> getDefaultConf() {
		SqlSession sess = CommonValues.factory.openSession();
		List<ParameterBean> result = sess.selectList(ConfigNames.SELECT_DEFAULCONF);
		sess.close();
		return result;
	}

	public static Cluster getClusterInfo(int clusterID) {
		SqlSession sess = CommonValues.factory.openSession();
		Cluster cluster = sess.selectOne(ConfigNames.SELECT_CLUSTER,clusterID);
		sess.close();
		return cluster;
	}
	
    public static List<String> getClusterNodes(int clusterID) {
		
		SqlSession sess = CommonValues.factory.openSession();
		
		//get cluster nodes and add new node ip
		List<String> nodeIpsList = sess.selectList(ConfigNames.SELECT_CLUSTER_NODE_IP,clusterID);
		sess.close();
		
		return nodeIpsList;
	}

	public static void updateClusterInfo(Cluster cluster) {
		
		SqlSession sess = CommonValues.factory.openSession(false);
		
		// update gtm master ip / gtm slave ip
		sess.insert(ConfigNames.UPDATE_CLUSTER_INFO,cluster);
		
		sess.commit();
		sess.close();
		
	}

	public static List<String> getClusterClients(int clusterID) {
		
		SqlSession sess = CommonValues.factory.openSession();
		
		//get cluster clients
		List<String> nodeIpsList = sess.selectList(ConfigNames.SELECT_CLUSTER_CLIENT_IP,clusterID);
		sess.close();
		
		return nodeIpsList;
	}
}
